package com.study.cloud.gateway.common.rule;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * 核心规则
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Rule implements Comparable<Rule>, Serializable {
    /**
     * 规则id
     */
    private String id;
    /**
     * 规则名称
     */
    private String name;
    /**
     *  协议 http dubbo
     */
    private String protocol;
    /**
     * 后端服务id
     */
    private String serverId;
    /**
     * 请求前缀
     */
    private String prefix;
    /**
     * 路径集合
     */
    private List<String> paths;
    /**
     * 规则排序，对应场景，一个路径对应多条规则，然后只执行一个规则
     */
    private Integer order;

    private Set<FilterConfig> filterConfigs = new HashSet<>();
    /**
     * 重试次数机制
     */
    private RetryConfig retryConfig = new RetryConfig();

    @Data
    public static class RetryConfig {
        private int times;
    }

    @Data
    public static class FilterConfig {
        /**
         * 过滤器唯一id
         */
        private String id;
        /**
         * 过滤器规则描述 {"timeout":10}
         */
        private String config;

        @Override
        public int hashCode() {
            return Objects.hashCode(id);
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj){
                return true;
            }
            if (obj == null || getClass() != obj.getClass()){
                return false;
            }
            FilterConfig that = (FilterConfig) obj;
            return id.equals(that.id);
        }
    }

    /**
     * 向规则中添加过滤器
     * @param config
     * @return
     */
    public boolean addFilterConfig(FilterConfig config){
        return filterConfigs.add(config);
    }

    /**
     * 功过指定id获取filter
     * @param id
     * @return
     */
    public FilterConfig getFilterConfig(String id){
        for (FilterConfig filterConfig : filterConfigs) {
            if (filterConfig.getId().equalsIgnoreCase(id)){
                return filterConfig;
            }
        }
        return null;
    }

    @Override
    public int compareTo(Rule o) {
        int orderCompare = Integer.compare(getOrder(),o.getOrder());
        if (orderCompare == 0){
            return getId().compareTo(o.getId());
        }
        return orderCompare;
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(id);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj){
            return true;
        }
        if (obj == null || getClass() != obj.getClass()){
            return false;
        }
        Rule that = (Rule) obj;
        return id.equals(that.id);
    }

}
